<template>
  <div class="app-container">
    <el-drawer
      :with-header="true"
      :visible.sync="drawer"
      :before-close="closeDrawer"
      size="1000px">
      <div slot="title" class="drawer-title">
        <span class="return-icon" @click="closeDrawer">
          <i class="el-icon-back" style="margin-right: 6px;"></i>返回 
        </span>
        <span class="return-icon">镜像ID：{{ this.drawerObj.id }}</span>
      </div>
      <div style="padding: 0 24px 24px 24px;">
        <JsonEditor ref="jsonEditor" v-model="imageInspect"></JsonEditor>
      </div>
    </el-drawer>

    <el-drawer
      :with-header="true"
      :visible.sync="createContainerDrawer"
      :before-close="closeCreateContainerDrawer"
      size="900px">
      <div slot="title" class="drawer-title">
        <span class="return-icon" @click="closeCreateContainerDrawer">
          <i class="el-icon-back" style="margin-right: 6px;"></i>返回 
        </span>
        <span class="return-icon">镜像名称：{{ this.drawerObj.name }}</span>
      </div>
      <el-form style="padding: 24px 24px 0px 24px;" :model="createContainerParams" ref="createContainerParams" :rules="createContainerForm" size="small" label-width="100px">
        <el-form-item label="容器名称：" prop="containerName">
          <el-row>
            <el-col :span="8">
              <el-input v-model="createContainerParams.containerName" placeholder="请输入内容容器名称" clearable></el-input>
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item label="端口：" prop="publishAllPorts">
          <template> 
            <el-radio v-model="createContainerParams.publishAllPorts" :label="false">指定端口</el-radio>
            <el-radio v-model="createContainerParams.publishAllPorts" :label="true">暴露所有</el-radio>
          </template>
          <template>
            <el-card v-if="!this.createContainerParams.publishAllPorts">
              <div>  
                <div v-for="(row, index) in createContainerParams.ports" :key="index" >  
                  <el-form :model="row" label-width="80px" label-position="top" style="margin-bottom: 5px;" ref="portForms" >  
                    <el-row :gutter="24">
                      <el-col :span="8" style="padding-left: 12px; padding-right: 3px;">
                        <el-form-item :label="controlLabelShow(index, '服务器端口')">
                          <el-input v-model="row.port" placeholder="例：80"></el-input>  
                        </el-form-item>  
                      </el-col>
                      <el-col :span="8" style="padding-left: 3px; padding-right: 3px;">
                        <el-form-item :label="controlLabelShow(index, '容器端口')" prop="containerPort" :rules="[{ required: true, message: ' ' }]">  
                          <el-input v-model="row.containerPort" placeholder="例：80"></el-input>  
                        </el-form-item>  
                      </el-col>
                      <el-col :span="6" style="padding-left: 3px; padding-right: 3px;">
                        <el-form-item :label="controlLabelShow(index, '协议')" prop="protocol" :rules="[{ required: true, message: ' ' }]"> 
                          <el-select v-model="row.protocol" placeholder="协议">
                            <el-option
                              v-for="dict in dict.type.docker_port_protocol"
                              :key="dict.value"
                              :label="dict.label"
                              :value="dict.value"
                            />
                          </el-select>
                        </el-form-item>
                      </el-col>
                      <el-col :span="2">
                        <el-form-item :label="controlLabelShow(index, '按钮')">  
                          <el-button type="text" size="mini" @click="deleteRowPorts(index)">删除</el-button>
                        </el-form-item>  
                      </el-col>
                    </el-row>
                  </el-form>  
                </div>  
              </div>  
              <el-button type="primary" size="mini" @click="addRowPorts">添加</el-button>
            </el-card>
          </template>
          <div style="color: gray;">
            端口映射允许容器内外通信
          </div>
        </el-form-item>
        <el-form-item label="网络：" prop="network">
          <el-select v-model="createContainerParams.network" placeholder="请选择" style="width: 95%;">
            <el-option v-for="item in createContainerParams.networkList" 
              :key="item.id" 
              :label="item.name" 
              :value="item.id">
            </el-option>
          </el-select>
          <div style="color: gray;">
            网络配置则决定容器如何与其他容器和外部通信
          </div>
        </el-form-item>
        <el-form-item label="挂载：" prop="volumes">
          <template>
            <el-card>
              <div>  
                <div v-for="(row, index) in createContainerParams.volumes" :key="index" >  
                  <el-form :model="row" label-width="80px" label-position="top" style="margin-bottom: 5px;" ref="volumeForms" >  
                    <el-row :gutter="24">
                      <el-col :span="5" style="padding-left: 12px; padding-right: 3px;">
                        <el-form-item :label="controlLabelShow(index, '挂载类型')" prop="volumeType" :rules="[{ required: true, message: ' ' }]">    
                          <el-select v-model="row.volumeType" placeholder="类型">
                            <el-option
                              v-for="dict in dict.type.docker_volume_type"
                              :key="dict.value"
                              :label="dict.label"
                              :value="dict.value"
                            />
                          </el-select>
                        </el-form-item> 
                      </el-col>
                      <el-col :span="7" style="padding-left: 3px; padding-right: 3px;" v-if="dict.type.docker_volume_type[0].value == row.volumeType">
                        <el-form-item :label="controlLabelShow(index, '目录')" prop="directory" :rules="[{ required: true, message: ' ' }]">      
                          <el-input v-model="row.directory" placeholder="请输入本机目录"></el-input>  
                        </el-form-item>  
                      </el-col>
                         <el-col :span="7" style="padding-left: 3px; padding-right: 3px;" v-if="dict.type.docker_volume_type[1].value == row.volumeType">
                        <el-form-item :label="controlLabelShow(index, '目录')" prop="directory" :rules="[{ required: true, message: ' ' }]">       
                          <el-select clearable v-model="row.directory" placeholder="请选择">
                            <el-option
                              v-for="item in createContainerParams.volumeList"
                              :key="item.name"
                              :label="item.name"
                              :value="item.name"
                              >
                              <span style="float: left">{{ item.name }}</span>
                            </el-option>
                          </el-select>
                        </el-form-item>  
                      </el-col>
                      <el-col :span="3" style="padding-left: 3px; padding-right: 3px;">
                        <el-form-item :label="controlLabelShow(index, '权限')" prop="accessMode" :rules="[{ required: true, message: ' ' }]">        
                          <el-select v-model="row.accessMode" placeholder="权限" clearable>
                            <el-option
                              v-for="dict in dict.type.docker_volume_auth"
                              :key="dict.value"
                              :label="dict.label"
                              :value="dict.value"
                            />
                          </el-select>
                        </el-form-item>
                      </el-col>
                      <el-col :span="7" style="padding-left: 3px; padding-right: 3px;">
                        <el-form-item :label="controlLabelShow(index, '容器目录')" prop="containerDirectory" :rules="[{ required: true, message: ' ' }]">         
                          <el-input v-model="row.containerDirectory"></el-input>  
                        </el-form-item>  
                      </el-col>
                      <el-col :span="2">
                        <el-form-item :label="controlLabelShow(index, '按钮')">  
                          <el-button type="text" size="mini" @click="deleteRowVolumes(index)">删除</el-button>
                        </el-form-item>  
                      </el-col>
                    </el-row>
                  </el-form>  
                </div>  
              </div>  
              <el-button type="primary" size="mini" @click="addRowVolumes">添加</el-button>
            </el-card>
          </template>
          <div style="color: gray;">
            挂载用于实现容器与宿主机文件系统的交互
          </div>
        </el-form-item>
        <el-form-item label="控制台交互：" prop="console">
          <div>
            <el-checkbox v-model="createContainerParams.console.t" label="为终端（-t）" border></el-checkbox>
            <el-checkbox v-model="createContainerParams.console.i" label="标准输入（-i）" border></el-checkbox>
          </div>
          <div style="color: gray;">
            -t 表示分配一个伪终端，-i 表示交互式连接，二者一同使用时可以实现容器与控制台的实时交互，使用户能够直接输入和查看容器内的命令输出，提供了更直观的控制台体验
          </div>
        </el-form-item>
        <el-form-item label="重启策略：" prop="restartPolicy.restart"> 
          <div>
            <el-radio v-for="dict in dict.type.docker_restart_strategy" v-model="createContainerParams.restartPolicy.restart" :label="dict.value">{{ dict.label }}</el-radio>
            <el-input-number v-model="createContainerParams.restartPolicy.maximumRetryCount" :min="1" :max="100" label="重启次数" v-if="createContainerParams.restartPolicy.restart == 'on-failure'" controls-position="right"></el-input-number>
          </div>
          <div style="color: gray;">
            重启策略指定了在容器意外退出时应该采取的行动
          </div>
        </el-form-item>
        <el-form-item label="CPU 权重：" prop="cpuShares"> 
          <div class="block">
            <el-slider v-model="createContainerParams.cpuShares" :min="0" :max="1024" show-input input-size="small" style="width: 95%;"></el-slider>
          </div>        
          <div style="color: gray;">
            为容器设置 CPU 权重，用于配置容器相对于其他容器的 CPU 共享权重，最高 1024
          </div>
        </el-form-item>
        <el-form-item label="CPU 核数：" prop="cpu"> 
          <div>
            <el-slider v-model="createContainerParams.cpu" show-input show-stops :step="1" :min="0" :max="createContainerParams.cpuMax" label="CPU" input-size="small" style="width: 95%;"></el-slider>
          </div>
          <div style="color: gray;">
            0 为默认大小，用于限制容器能够使用的 CPU 核心数量，当前服务器最大可用为 {{ this.createContainerParams.cpuMax }} 核
          </div>
        </el-form-item>
        <el-form-item label="内存限制：" prop="memory"> 
          <div class="block">
            <el-slider v-model="createContainerParams.memory" :step="50" :min="0" :max="createContainerParams.memTotal" show-input input-size="small" style="width: 95%;"></el-slider>
          </div>        
          <div style="color: gray;">
            0 为默认大小，用于限制容器能够使用的物理内存的大小，最大可用为 {{ this.createContainerParams.memTotal }}MB
          </div>
        </el-form-item>
        <el-form-item label="标签：" prop="labels">
          <template>
            <el-input style="width: 45%;" type="textarea" :autosize="{ minRows: 4, maxRows: 10}" 
              :placeholder="targetPlaceholder" v-model="createContainerParams.labels"></el-input>
          </template>
        </el-form-item>
        <el-form-item label="环境变量：" prop="envs">
          <template>
            <el-input style="width: 45%;" type="textarea" :autosize="{ minRows: 4, maxRows: 10}" 
              :placeholder="targetPlaceholder" v-model="createContainerParams.envs"></el-input>
          </template>
        </el-form-item>
        <el-form-item label="CMD：" prop="cmd">
          <el-row>
            <el-col :span="24">
              <el-input v-model="createContainerParams.cmd" placeholder="例：'nginx' '-g' 'daemon off;' 或者 nginx -g daemon off;" clearable style="width: 95%;"></el-input>
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item label="Entrypoint：" prop="entrypoint">
          <el-row>
            <el-col :span="24">
              <el-input v-model="createContainerParams.entrypoint" placeholder="例：/bin/sh -c" clearable style="width: 95%;"></el-input>
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-mouse" size="mini" @click="createContainer()">保存</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>

    <el-drawer
      title="操作镜像"
      :with-header="false"
      :visible.sync="searchImageDrawer"
      :before-close="closeSearchImageDrawer"
      size="900px">
      <div style="padding: 24px 18px 0px 24px;">
        <template>
          <el-tabs v-model="activeName" tab-position="top" @tab-click="tabHandleClick">
            <el-tab-pane label="拉取镜像" name="pull">
              <template>
                <div style="padding: 0 8px 8px 8px;">
                  <el-input clearable size="mini" show-word-limit placeholder="请输入镜像名称以及Tag # nginx:laster" v-model="searchImageName">
                    <el-button 
                      required
                      slot="append" 
                      icon="el-icon-mouse"
                      @click="handelPullBySearchImageName"
                      v-hasPermi="['docker:image:pull']"
                    >下载</el-button>
                  </el-input>
                </div>
              </template>
            </el-tab-pane>
            <el-tab-pane label="搜索镜像" name="search">
              <template>
                <div style="padding: 0 8px 8px 8px;">
                  <el-input clearable size="mini" show-word-limit placeholder="请输入镜像名称" v-model="searchImageName">
                    <el-button 
                      required
                      slot="append" 
                      icon="el-icon-search"
                      @click="handleSearchImage"
                      v-hasPermi="['docker:image:add']"
                    >搜索</el-button>
                  </el-input>
                </div>
                <div style="padding: 8px 8px 8px 8px;">
                  <el-table stripe v-loading="loading" :data="imagePullList" size="mini" :header-cell-style="{'text-align':'left'}" >
                    <el-table-column label="镜像名称" show-overflow-tooltip min-width="23%" align="left" prop="name" />
                    <el-table-column label="Star" show-overflow-tooltip min-width="13%" align="left" prop="starCount" >
                      <template slot-scope="scope">
                        <i class="el-icon-star-on"></i>
                        <span style="margin-left: 3px">{{ scope.row.starCount }}</span>
                      </template>
                    </el-table-column>
                    <el-table-column label="官方" min-width="10%" align="left" prop="isOfficial">
                      <template slot-scope="scope">
                        <dict-tag :options="dict.type.sys_yes_no_boolean" :value="scope.row.isOfficial"/>
                      </template>
                    </el-table-column>
                    <el-table-column label="DockerFIle" min-width="13%" align="left" prop="isAutomated">
                      <template slot-scope="scope">
                        <dict-tag :options="dict.type.sys_yes_no_boolean" :value="scope.row.isAutomated"/>
                      </template>
                    </el-table-column>
                    <el-table-column label="描述" show-overflow-tooltip min-width="35%" align="left" prop="description" />
                    <el-table-column label="操作" min-width="16%" align="left" lign="center" class-name="small-padding fixed-width" fixed="right">
                      <template slot-scope="scope">
                        <el-button
                          size="mini"
                          type="text"
                          icon="el-icon-mouse"
                          @click="handlePull(scope.row)"
                          v-hasPermi="['docker:image:pull']"
                        >拉取</el-button>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </template>
            </el-tab-pane>
            <el-tab-pane label="构建镜像" name="build" v-hasPermi="['docker:image:build']">
              <template>
                <div style="padding: 24px 24px 0px 24px;">
                  <el-form :model="buildImageParams" ref="buildImageParams" :rules="buildImageForm" size="small" label-width="88px">
                    <el-row>
                      <el-col :span="12">
                        <el-form-item label="名称" prop="imageName">
                          <el-input clearable v-model="buildImageParams.imageName" placeholder="镜像名称及 Tag，例：nginx:latest">
                          </el-input>
                        </el-form-item>
                      </el-col>
                    </el-row>
                    <el-form-item label="Dockerfile：" prop="editDockerfile">
                      <template> 
                        <el-radio v-model="buildImageParams.editDockerfile" :label="true">编辑</el-radio>
                        <el-radio v-model="buildImageParams.editDockerfile" :label="false">路径选择</el-radio>
                      </template>
                      <template>
                        <div style="margin-top: 10px;">
                          <div v-if="this.buildImageParams.editDockerfile">
                            <editor
                              height="200px" 
                              width="95%"
                              ref="editor" 
                              :content="buildImageParams.content" 
                              v-model="buildImageParams.content"
                              theme="monokai"
                              :options="{
                                showPrintMargin: false,
                                showLineNumbers: false,
                                showGutter: false,
                                enableBasicAutocompletion: false,
                                enableSnippets: true,
                                enableLiveAutocompletion: false,
                                tabSize: 2,
                                fontSize: 14,
                                showPrintMargin: false,
                              }"
                              :lang="'text'"
                              @init="editorInit">
                            </editor>
                          </div>
                          <div v-if="!this.buildImageParams.editDockerfile">
                            <el-input placeholder="请输入内容" v-model="buildImageParams.contentPath">
                              <el-button slot="prepend" icon="el-icon-folder"></el-button>
                            </el-input>
                          </div>
                        </div>
                      </template>
                    </el-form-item>
                    <el-form-item label="使用缓存：" prop="nocache">
                      <template>
                        <el-radio v-model="buildImageParams.nocache" :label="false">使用</el-radio>
                        <el-radio v-model="buildImageParams.nocache" :label="true">不使用</el-radio>
                      </template>
                    </el-form-item>
                    <el-form-item label="标签：" prop="label">
                      <template>
                        <el-input style="width: 95%;" type="textarea" :autosize="{ minRows: 4, maxRows: 10}" 
                          :placeholder="targetPlaceholder" v-model="buildImageParams.label"></el-input>
                      </template>
                    </el-form-item>
                    <el-form-item>
                      <el-button type="primary" icon="el-icon-mouse" size="mini" @click="handleBuildImage">构建</el-button>
                      <el-button icon="el-icon-refresh" size="mini" @click="resetBuildImageParams">重置</el-button>
                    </el-form-item>
                  </el-form>
                </div>
              </template>
            </el-tab-pane>
            <el-tab-pane label="导入镜像" name="export" v-hasPermi="['docker:image:export']">
              <template>
                <div style="padding: 0 8px 8px 8px;">
                  <el-input clearable size="mini" show-word-limit placeholder="镜像名称" v-model="searchImageName">
                    <el-button 
                      required
                      slot="append" 
                      icon="el-icon-mouse"
                      @click=""
                    >导入</el-button>
                  </el-input>
                </div>
              </template>
            </el-tab-pane>
            <el-tab-pane label="清理镜像" name="clean" v-hasPermi="['docker:image:clean']">
              <template>
                <div class="clean-image-tab">
                  <div class="radio-group">
                    <el-radio v-model="cleanRadio" label="1">没标签且的未使用的镜像</el-radio>
                    <el-radio v-model="cleanRadio" label="0">未使用的镜像</el-radio>
                  </div>
                  <div class="image-list">
                    <div style="flex: 1;">{{ this.cleanRadio == '1' ? '清理下列标签为 none 且未被任何容器使用的镜像。' : '清理下列未被任何容器使用的镜像。' }}</div>
                    <div class="button-container">
                      <el-button
                        type="text"
                        required
                        slot="append"
                        icon="el-icon-mouse"
                        @click="pruneImage"
                      >确认清除</el-button>
                    </div>
                  </div>
                  <div v-for="(item, index) in noneImageList" :key="index">
                    <ul><li>{{ item }}</li></ul>
                  </div>
                </div>
              </template>
            </el-tab-pane>
          </el-tabs>
        </template>
      </div>
    </el-drawer>

    <el-form :model="queryParams" ref="queryParams" :rules="form" size="small" :inline="true" v-show="showSearch" label-width="88px">
      <el-form-item label="设备名称" prop="deviceId">
        <el-select clearable v-model="queryParams.deviceId" placeholder="请选择" @focus="getListConfig">
          <el-option
            v-for="item in configList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
            :disabled="item.disabled"
            >
            <span style="float: left">{{ item.name }}</span>
            <span :style="{float: 'right', color:  item.colorPicker ? item.colorPicker : '#000000' , fontSize: '13px'}">{{ item.status }}</span>
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="镜像名称" prop="imageName">
        <el-input
          v-model="queryParams.imageName"
          placeholder="请输入镜像名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="镜像ID" prop="imageId">
        <el-input 
          v-model="queryParams.imageId" 
          placeholder="请输入镜像ID" 
          clearable 
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" v-hasPermi="['docker:image:list']" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="showHandleImageDrawer('pull')"
          v-hasPermi="['docker:image:pull']"
        >拉取镜像</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-office-building"
          size="mini"
          @click="showHandleImageDrawer('build')"
          v-hasPermi="['docker:image:build']"
        >构建镜像</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          size="mini"
          @click="showHandleImageDrawer('export')"
          v-hasPermi="['docker:image:export']"
        >导入镜像<i class="el-icon-upload el-icon--right"></i></el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          @click="showHandleImageDrawer('clean')"
          v-hasPermi="['docker:image:clean']"
        >清理镜像</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table stripe v-loading="loading" :data="imageList" @selection-change="handleSelectionChange" :header-cell-style="{'text-align':'left'}" >
      <el-table-column label="镜像名称" show-overflow-tooltip min-width="45%" align="left" prop="name" >
        <template slot-scope="scope">
          <div class="table-link" @click="showDrawer(scope.row)"> {{ scope.row.name }} </div>
        </template>
      </el-table-column>
      <el-table-column label="状态" min-width="22%" align="left" prop="status">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.docker_image_usage_status" :value="scope.row.status"/>
        </template>
      </el-table-column>
      <el-table-column label="TAG" min-width="52%" align="left" prop="tag" >
        <template slot-scope="scope">
          <el-tag slot="reference" type="text" size="small">
            {{ scope.row.tag.length > 35 ? scope.row.tag.substr(0, 35) + '...' : scope.row.tag }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="占用大小" min-width="20%" align="left" prop="occupiedSpace" />      
      <el-table-column label="创建时间" min-width="35%" align="left" prop="createTime" >
        <template slot-scope="scope">
          <i class="el-icon-time"></i>
          <span style="margin-left: 10px">{{ scope.row.createTime }}</span>
        </template>
      </el-table-column>
      <el-table-column show-overflow-tooltip label="镜像ID" min-width="35%" align="left" prop="id" >
        <template slot-scope="scope">
          <i class="el-icon-document-copy" @click="$handleCopy(scope.row.id, $event)"></i><span style="margin-left: 10px">{{ scope.row.id }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" min-width="56%" align="left" lign="center" class-name="small-padding fixed-width" fixed="right">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-caret-right"
            @click="handleCreateContainer(scope.row)"
            v-hasPermi="['revolution:container:start']"
          >启动</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-download"
            @click="handleExport(scope.row)"
            v-hasPermi="['docker:image:download']"
          >导出</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['docker:image:delete']"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />
  </div>
</template>

<script>
import { listImage, delImage, searchImage, pullImage, getImageDetail, listNoneImage, pruneImage, getImagePort, buildImage } from "@/api/docker/image";
import { listConfig as configListConfig} from "@/api/docker/config";
import { addContainer } from "@/api/docker/container";
import { listVolume } from "@/api/docker/volume";
import { listNetwork } from "@/api/docker/network";

export default {
  components: {
    editor: require("vue2-ace-editor"),
  },
  name: "Config",
  dicts: ['sys_yes_no', 'docker_status', 'docker_image_usage_status', 'sys_yes_no_boolean', 'docker_port_protocol', 'docker_volume_type', 'docker_volume_auth', 'docker_restart_strategy'],
  data() {
    return {
      activeName: 'second', 
      // 清理镜像选择
      cleanRadio: "1",
      // 拉取镜像搜索框
      searchImageName: "",
      // 镜像信息
      imageInspect: {},
      // 抽屉
      drawer: false,
      // 查询镜像抽屉
      searchImageDrawer: false,
      // 启动镜像抽屉
      createContainerDrawer: false,
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 未使用的镜像
      noneImageList: [],
      // docker 信息表格数据
      configList: [],
      // docker 信息表格数据
      imageList: [],
      // remote image 信息表格数据
      imagePullList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        deviceId: null,
        imageName: null,
        imageId: null,
      },
      // 创建容器参数
      createContainerParams: {
        imageId: null,
        containerName: null,
        publishAllPorts: true,
        ports: [],
        volumes: [],
        network: null,
        cmd: null,
        entrypoint: null,
        console: {
          t: true,
          i: true
        },
        restartPolicy: {
          restart: 'no',
          maximumRetryCount: 5,
        },
        cpuShares: 1024,
        cpu: 0,
        cpuMax: 0,
        memTotal: 0,
        memory: null,
        labels: null,
        envs: null,
        imageId: null,
        deviceId: null,
        networkList: [],
        volumeList: []
      },  
      // 编辑器
      showEditor: false,
      // 构建镜像参数
      initBuildImageParams: {
        imageName: null,
        content: '',
        contentPath: null,
        editDockerfile: true,
        nocache: false,
        label: null
      },
      // 构建镜像参数
      buildImageParams: {
        imageName: null,
        content: '',
        contentPath: null,
        editDockerfile: true,
        nocache: false,
        label: null
      },
      // 表单参数
      form: { 
        deviceId: [
          { required: true, message: "请先选择设备", trigger: "blur" }
        ]
      },
      // 构建镜像校验
      buildImageForm: {
        imageName: [
          { required: true, message: "名称不能为空", trigger: "blur" }
        ],
        editDockerfile: [
          { required: true, message: "名称不能为空", trigger: "blur" }
        ],
      },
      createContainerForm: {
        containerName: [
          { required: true, message: "容器名称不能为空", trigger: "blur" },
        ],
        publishAllPorts: [
          { required: true, message: "请选择端口", trigger: "blur" }
        ],
        network: [
          { required: true, message: "请选择网络", trigger: "blur" }
        ],
        restart: [
          { required: true, message: "请选择重启策略", trigger: "blur" }
        ],
      },
      // 表单校验
      rules: {
        name: [
          { required: true, message: "自定义名称不能为空", trigger: "blur" }
        ],
      },
      drawerObj: {

      },
      // placeholder
      targetPlaceholder: "一行一个回车换行，\nkey1=value1\nkey2=value2"
    };
  },
  created() {
    this.getListConfig();
  },
  methods: {
    editorInit() {
      require("brace/theme/monokai");
    },
    /** 重置构建镜像 */
    resetBuildImageParams() {
      this.buildImageParams = { ...this.initBuildImageParams }
    },
    /** 重置构建镜像 */
    handleBuildImage() {
      this.$refs["buildImageParams", "queryParams"].validate(valid => {
        if (valid) {
          this.buildImageParams.deviceId = this.queryParams.deviceId
          buildImage(this.buildImageParams).then(response => {
            this.$modal.msgSuccess(response.msg);
          });
        }
      });
    },
    /** 启动镜像 - 删除一行端口 */
    deleteRowPorts(index) {
      this.createContainerParams.ports.splice(index, 1)
    },
    /** 启动镜像 - 删除一行端口 */
    deleteRowVolumes(index) {
      this.createContainerParams.volumes.splice(index, 1)
    },
    /** 启动镜像 - 添加一行端口 */
    addRowPorts() {  
      this.createContainerParams.ports.push({ 
        'port': null, 
        'containerPort': null, 
        'protocol': this.dict.type.docker_port_protocol[0].value
      });  
    },
    /** 启动镜像 - 添加一行挂载点 */
    addRowVolumes() {
      this.createContainerParams.volumes.push({ 
        'volumeType': this.dict.type.docker_volume_type[0].value, 
        'directory': null, 
        'accessMode': this.dict.type.docker_volume_auth[0].value, 
        'containerDirectory': null });  
    },
    /** 删除虚镜像 */
    pruneImage() {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          pruneImage({ 
            deviceId : this.queryParams.deviceId,
            dangling : this.cleanRadio
          }).then(response => {
            this.$modal.msgSuccess(response.msg);
            this.tabHandleByName('clean');
            this.getList();
          });
        }
      });
    },
    /** 切换 tab label */
    tabHandleClick(tag) {
      this.tabHandleByName(tag.name);
    },
    /** 根据 tab name 处理信息 */
    tabHandleByName(name) {
      if (name == 'clean') {
        this.$refs["queryParams"].validate(valid => {
          if (valid) {
            listNoneImage({ 
              deviceId : this.queryParams.deviceId,
              dangling : this.cleanRadio
            }).then(response => {
              this.noneImageList = response.data;
            });
          }
        });
      }
    },
    /** 开启抽屉 */
    showDrawer(row) {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          this.drawerObj = row;
          getImageDetail({ 'deviceId' : this.queryParams.deviceId, 'imageId' : row.id }).then(response => {
            this.drawer = true;
            this.imageInspect = response.data;
          });
        }
      });
    },
    /** 开启启动镜像抽屉 */ 
    handleCreateContainer(row) {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          this.drawerObj = row;
          this.createContainerDrawer = true;
          getImagePort({ 'deviceId' : this.queryParams.deviceId, 'imageId' : row.id }).then(response => {
            this.getNetworks();
            this.getVolumes();
            this.createContainerParams.imageId = row.id;
            this.createContainerParams.cpu = response.data.cpu;
            this.createContainerParams.ports = response.data.ports;
            if (response.data.volumes) {
              response.data.volumes.forEach(data => {
                data.volumeType = this.dict.type.docker_volume_type[0].value;
                data.accessMode = this.dict.type.docker_volume_auth[0].value;
              }) 
              this.createContainerParams.volumes = response.data.volumes;
            }
            this.createContainerParams.cpuMax = response.data.cpuMax;
            this.createContainerParams.memTotal = response.data.memTotal;
          });
        }
      });
    },
    /** 查询网络 */
    getNetworks() {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          listNetwork({ 'deviceId' : this.queryParams.deviceId, 'pageNum': 1, 'pageSize': 9999 }).then(response => {
            response.data.forEach(data => {
              if (data.name === 'bridge' && this.createContainerParams.network == null) {
                this.createContainerParams.network = data.id;
              }
            })
            this.createContainerParams.networkList = response.data;
          });
        }
      });
    },
    /** 查询挂载点 */
    getVolumes() {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          listVolume({ 'deviceId' : this.queryParams.deviceId, 'pageNum': 1, 'pageSize': 9999 }).then(response => {
            this.createContainerParams.volumeList = response.data;
          });
        }
      });
    },
    /** 关闭抽屉 */
    closeDrawer() {
      this.drawer = false;
      this.drawerObj = {};
      this.imageInspect = {};
    },
    /** 关闭镜像搜索抽屉 */
    closeSearchImageDrawer() {
      this.showEditor = false;
      this.buildImageParams = { ...this.initBuildImageParams };
      this.searchImageDrawer = false;
      this.searchImageName = '';
      this.imagePullList = [];
      this.noneImageList = [];
      this.activeName = 'second';
      this.cleanRadio = "1";
      this.searchImageName = "";
    },
    /** 启动镜像抽屉 */
    closeCreateContainerDrawer() {
      this.createContainerDrawer = false;
      this.drawerObj = {};
    },
    /** 查询 容器配置 信息列表 */
    getListConfig() {
      this.loading = false;
      const statusDict = {};
      configListConfig({ 'pageNum': 1, 'pageSize': 9999 }).then(response => {
        this.dict.type.docker_status.forEach(d => {
          statusDict[d.value] = d;
        });
        this.configList = response.data.map(r => ({
          ...r, 
          status: statusDict[r.status].label || r.status,
          disabled: r.status == 0 ? true : false,
          colorPicker: statusDict[r.status].raw.colorPicker
        }));
      });
    },
    /** 查询 image 信息列表 */
    getList() {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          this.loading = true;
          listImage(this.queryParams).then(response => {
            response.data.forEach(i => {
              i.id = i.id.replace('sha256:', '');
              i.name = i.name;
              i.tag = i.tag;
            });
            
            this.imageList = response.data;
            this.total = response.total;
            this.loading = false;
          }).catch(err => {
            this.loading = false;
          });
        }
      });
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
      this.imageList = [];
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryParams");
      this.getListConfig();
      this.imageList = [];
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length!==1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    showHandleImageDrawer(activeName) {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          this.showEditor = true;
          this.activeName = activeName;
          this.searchImageDrawer = true;
        }
      });
    },
    /** 搜索远程镜像操作 */
    handleSearchImage() {
      var searchImageName = this.searchImageName;
      if (searchImageName === '') {
        this.$message.error('请输入镜像名称后查询');
        return;
      }
      searchImage({'imageName' : searchImageName}).then(response => {
        this.imagePullList = response.data;
      });
    },
    /** 根据录入名称拉取镜像 */
    handelPullBySearchImageName() {
      var searchImageName = this.searchImageName;
      if (searchImageName === '') {
        this.$message.error('请输入镜像名称后下载');
        return;
      }
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          var imageName = searchImageName;
          pullImage({ 'deviceId' : this.queryParams.deviceId, 'imageName' : imageName }).then(response => {
            this.$modal.msgSuccess(response.data.msg);
          });
        } 
      });
    },
    /** 拉取镜像 */
    handlePull(row) {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          var imageName = row.name;
          pullImage({ 'deviceId' : this.queryParams.deviceId, 'imageName' : imageName }).then(response => {
            this.$modal.msgSuccess("下载中，请留意通知中心!");
          });
        } 
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const id = row.id;
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          var queryParams = { 'deviceId' : this.queryParams.deviceId, 'imageName' : row.name, 'tag' : row.tag }
          this.$modal.confirm('是否确认删除编号为 "' + row.name + ":" + row.tag + '" 的数据项？').then(function() {
            return delImage(queryParams);
          }).then(() => {
            this.getList();
            this.$modal.msgSuccess("删除成功");
          }).catch(() => {});
        }
      });
    },
    /** 导出按钮操作 */
    handleExport(row) {
      this.$refs["queryParams"].validate(valid => {
        if (valid) {
          var queryParams = { 'deviceId' : this.queryParams.deviceId, 'imageId' : row.id }
          this.download('docker/image/save', {
            ...queryParams
          }, 'aa.tar')
        }
      });
    },
    /** 控制 label 显示 */
    controlLabelShow(index, label) {
      if (index == 0) {
        return label;
      }
      return null;
    },
    /** 创建容器 */
    createContainer() {
      var _valid = true;
      if (!this.createContainerParams.publishAllPorts) {
        this.$refs["portForms"].forEach(form => {
          form.validate(valid => {
            if (!valid) {
              _valid = false;
            }
          });
        });
      }
      if (this.createContainerParams.volumes.length != 0) {
        this.$refs["volumeForms"].forEach(form => {
          form.validate(valid => {
            if (!valid) {
              _valid = false;
            }
          });
        });
      }
      this.$refs["queryParams", "createContainerParams"].validate(valid => {
        if (valid && _valid) {
          this.createContainerParams.deviceId = this.queryParams.deviceId
          addContainer(this.createContainerParams).then(() => {
            this.getList();
            this.$modal.msgSuccess("容器创建成功");
          }).catch(() => {
            this.$modal.error("容器创建失败");
          });
        }
      });
    }
  },
  watch: {
    activeName(newValue, oldValue) {
      if (newValue !== oldValue && this.searchImageDrawer) {
        this.tabHandleByName(newValue);
      }
    },
    cleanRadio(newValue, oldValue) {
      if (newValue !== oldValue && this.searchImageDrawer) {
        this.tabHandleByName('clean');
      }
    },
  },
};
</script>

<style>
  .font-item {
    font-size: 14px;
    padding: 2px 0;
  }
  .table-link {
      color: #005eeb;
      font-weight: 700;
      cursor: pointer;
  }
  .clean-image-tab {
    padding: 0 8px 8px 8px;
  }
  .radio-group {
    padding: 15px;
  }
  .image-list {
    display: flex;
    align-items: center;
    margin-top: 15px;
  }
  .button-container {
    margin-left: 10px;
  }
  .table-expand {
    font-size: 0;
  }
  .table-expand label {
    width: 80px;
    color: #99a9bf;
  }
  .table-expand .el-form-item {
    margin-right: 0;
    margin-bottom: 0;
    width: 25%;
  }
  .item {
    display: inline-block;
    vertical-align: middle;
  }
  .text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 250px; /* 超出150px后显示省略号 */
  }
  .drawer-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px;
    border-bottom: 1px solid rgb(218, 218, 218);
    font-size: 15px;
    font-weight: 500;
  }
  .return-icon {
    cursor: pointer;
    display: flex;
    align-items: center;
    color: #676a6d;
  }
  .el-drawer__header {
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    color: #72767b;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    margin-bottom: 16px;
    padding: 20px;
    padding-bottom: 0;
  }
  .el-card.el-card.is-always-shadow {
    width: 95%; 
    margin: 10px 0px;
    box-shadow: 0 0.5px 2px rgba(0, 0, 0, 0.1); /* 调整阴影效果 */
  }
  .el-form-item--small.el-form-item {
    margin-bottom: 23px;
  }
  .el-checkbox {
    margin-right: 3px;
  }
</style>
